package com.edu.juc.lock.readWriteLock;

import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * 读写锁被定义为：
 * 一个资源能够被多个读线程访问，或者被一个写线程访问，但是不能同时存在读写线程。
 * 缺点： 1.写锁饥饿问题 2. 注意锁降级
 * 读写锁只允许读读共存，而读写和写写依然是互斥的。
 */
public class ReentrantReadWriteLockTest {
    public static void main(String[] args) {

        // 独占锁
        ReentrantLock reentrantLock = new ReentrantLock();
        reentrantLock.lock();
        reentrantLock.unlock();


        // 可重入读写锁对象
        // 重入允许通过获取写入锁定，然后读取锁，然后释放写锁从写锁到读锁。
        ReentrantReadWriteLock rwLock = new ReentrantReadWriteLock();
        ReentrantReadWriteLock.ReadLock readLock = rwLock.readLock(); // 读锁
        ReentrantReadWriteLock.WriteLock writeLock = rwLock.writeLock(); // 写锁

        // 锁降级
        // 获取写锁
        writeLock.lock();
        System.out.println("Hello, ");

        // 获取读锁
        readLock.lock();
        System.out.println("World!");
//        writeLock.unlock();
        readLock.unlock();
        System.out.println("!!!");
//        writeLock.unlock();
        new Thread(() -> {
            readLock.lock();
            System.out.println("new Thread ---");
            readLock.unlock();
        }).start();

        // 锁升级： 读锁不能升级为写锁！！（悲观锁策略）
        // 获取读锁
//        readLock.lock();
//        System.out.println("World!");
////         获取写锁
//        writeLock.lock();
//        System.out.println("Hello, ");
//
//
//        writeLock.unlock();
//        readLock.unlock();
    }
}
